/// @tags:
#include <cctype>
#include <cstdio>
#include <map>
#include <set>

namespace BlueQuantum {

typedef long long ll;

int const N = 1e3 + 5, Q = 5e5 + 5, mod = 1e9 + 7;

template <typename T>
inline T &read(T &x) {
  x = 0;
  bool f = false;
  short ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = true;
    ch = getchar();
  }
  while (isdigit(ch)) x = x * 10 + (ch ^ '0'), ch = getchar();
  if (f) x = -x;
  return x;
}

struct Node {
  int l, r;
  inline bool operator<(Node const &rhs) const { return r != rhs.r ? r < rhs.r : l < rhs.l; }
};

int n, m, q, used;
int spos[N], sr[N], top, num[N], numlen;
typedef std::set<Node>::iterator iter;
std::set<int> set[N];
std::set<Node> odt[Q];
std::map<int, int> map;

inline int qpow(int a, int b) {
  int re = 1;
  for (; b; b >>= 1, a = (ll)a * a % mod) b & 1 ? re = (ll)re * a % mod : 0;
  return re;
}

inline int main() {
  read(n), read(m), read(q);
  for (int x, c, opt; q; --q) {
    switch (read(opt)) {
      case 1:
        read(x), c = m - read(c);
        if (!set[x].empty() && *set[x].lower_bound(c) == c) {
          set[x].erase(c);
          int id = map[c];
          iter tmp = odt[id].lower_bound((Node){0, x});
          odt[id].erase(tmp);
          if (tmp->l != x) odt[id].insert((Node){tmp->l, x - 1});
          if (tmp->r != x) odt[id].insert((Node){x + 1, tmp->r});
        } else {
          set[x].insert(c);
          int id = map.find(c) == map.end() ? map[c] = ++used : map[c];
          iter tmp = odt[id].lower_bound((Node){0, x}), tmp2 = tmp;
          bool lchk = false, rchk = false;
          if (tmp != odt[id].begin()) { --tmp, lchk = tmp->r == x - 1; }
          if (tmp2 != odt[id].end()) { rchk = tmp2->l == x + 1; }
          if (lchk && rchk) {
            odt[id].erase(tmp), odt[id].erase(tmp2), odt[id].insert((Node){tmp->l, tmp2->r});
          } else if (lchk) {
            odt[id].erase(tmp), odt[id].insert((Node){tmp->l, x});
          } else if (rchk) {
            odt[id].erase(tmp2), odt[id].insert((Node){x, tmp2->r});
          } else
            odt[id].insert((Node){x, x});
        }
        break;
      case 2:
        int ans = 0, nowans;
        if (set[1].empty()) {
          ans = -1;
          goto end;
        }
        num[numlen = 1] = *set[1].begin();
        spos[top = 1] = 1;
        sr[1] = odt[map[num[1]]].begin()->r;
        ans = nowans = qpow(2, num[1]);
        for (int i = 2; i <= n; ++i) {
          if (set[i].empty()) {
            ans = -1;
            goto end;
          }
          std::set<int>::iterator tmp = set[i].begin();
          if (sr[top] < i) {
            while (top && sr[top] < i) --top;
            while (numlen > spos[top + 1])
              nowans = (nowans - qpow(2, num[numlen]) + mod) % mod, --numlen;
            goto ctn;
          } else {
            if (*tmp != num[numlen]) {
              num[++numlen] = *tmp;
              nowans = (nowans + qpow(2, num[numlen])) % mod;
              int tmpr = odt[map[num[numlen]]].lower_bound((Node){0, i})->r;
              if (tmpr < sr[top]) sr[++top] = tmpr, spos[top] = numlen;
              ans = (ans + nowans) % mod;
            } else {
            ctn:
              int ok = 0;
              while (numlen > 1) {
                if (*(tmp = set[i].upper_bound(num[numlen])) != num[numlen - 1]) {
                  nowans = (nowans - qpow(2, num[numlen]) + mod) % mod;
                  --numlen;
                  ok = 1;
                  while (spos[top] > numlen) --top;
                  num[++numlen] = *tmp;
                  nowans = (nowans + qpow(2, num[numlen])) % mod;
                  int tmpr = odt[map[num[numlen]]].lower_bound((Node){0, i})->r;
                  if (tmpr < sr[top]) sr[++top] = tmpr, spos[top] = numlen;
                  ans = (ans + nowans) % mod;
                  ok = 1;
                  break;
                }
                nowans = (nowans - qpow(2, num[numlen]) + mod) % mod;
                --numlen;
              }
              if (!ok) {
                if ((tmp = set[i].upper_bound(num[1])) == set[i].end()) {
                  ans = -1;
                  goto end;
                }
                num[numlen = 1] = *tmp;
                spos[top = 1] = 1, sr[top] = odt[map[num[1]]].lower_bound((Node){0, i})->r,
                           nowans = qpow(2, num[1]);
                ans = (ans + nowans) % mod;
              }
            }
          }
        }
      end:
        printf("%d\n", ans);
    }
  }
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("price.in", "r", stdin);
  freopen("price.out", "w", stdout);
#endif
#endif

  return BlueQuantum::main();
}